﻿using System;
using System.IO;
using System.Linq;
using ExcelAutomator.Configuration;
using ExcelAutomator.Validation;
using NUnit.Framework;

namespace ExcelAutomator.Tests
{
	public class ExcelServiceTestFixture : ExcelTestFixtureBase
	{

		#region ProcessSingleInputFile_With_RelativePath
		[Test]
		public void ProcessSingleInputFile_With_RelativePath()
		{
			var cfg = new ExcelAutomatorConfiguration(){Settings = new SettingsConfiguration()
			                                                       	{
			                                                       		Input = "Input\\" + SourceWbName
			                                                       	}};
			var sut = new ExcelAutomationService(cfg);

			Assert.That(sut.InputFiles.Count, Is.EqualTo(1));
			Assert.That(sut.InputFiles.First(), Is.EqualTo(Path.Combine(InputFolderPath, SourceWbName)));
			
		}
		#endregion

		#region ProcessSingleInputFile_With_Absolute_Path
		[Test]
		public void ProcessSingleInputFile_With_Absolute_Path()
		{
			var cfg = new ExcelAutomatorConfiguration(){
				Settings = new SettingsConfiguration()
				           	{
				           		Input = Path.Combine(Path.Combine(Environment.CurrentDirectory,"Input"), SourceWbName)
				           	}};
			
			var sut = new ExcelAutomationService(cfg);

			Assert.That(sut.InputFiles.Count, Is.EqualTo(1));
			Assert.That(sut.InputFiles.First(), Is.EqualTo(Path.Combine(this.InputFolderPath, SourceWbName)));
		}
		#endregion

		#region FailValidationIfSingleInputFileCannotBeFound
		[Test]
		public void FailValidationIfSingleInputFileCannotBeFound()
		{
			var cfg = new ExcelAutomatorConfiguration()
			          	{
			          		Settings = new SettingsConfiguration()
			          		           	{
			          		           		Input = "Foobar_no_existing.xls"
			          		           	}
			          	};

			var sut = new ExcelAutomationService(cfg);

			ValidationReport report;
			sut.Validate(out report);

			Assert.That(report.IsValid, Is.False);
			Assert.That(report.ViolationsCount, Is.EqualTo(1));

		}
		#endregion

		#region FailValidationIfInputFolderCannotBeFound
		[Test]
		public void FailValidationIfInputFolderCannotBeFound()
		{
			var cfg = new ExcelAutomatorConfiguration()
			{
				Settings = new SettingsConfiguration()
				{
					Input = "FooFolder"
				}
			};

			var sut = new ExcelAutomationService(cfg);

			ValidationReport report;
			sut.Validate(out report);
			Assert.That(report.IsValid, Is.False);
			Assert.That(report.ViolationsCount, Is.EqualTo(1));

		}
		#endregion

		#region FailValidationIfFolderHasNoInputFiles
		[Test]
		public void FailValidationIfFolderHasNoInputFiles()
		{
			Directory.CreateDirectory(EmptyInputFolderPath);
			var cfg = new ExcelAutomatorConfiguration()
			{
				Settings = new SettingsConfiguration()
				{
					Input = EmptyInputFolderPath
				}
			};

			var sut = new ExcelAutomationService(cfg);
			ValidationReport report;
			sut.Validate(out report);

			Assert.That(report.IsValid, Is.False);
			Assert.That(report.ViolationsCount, Is.EqualTo(1));

		}
		#endregion

		#region ProcessInputFolder
		[Test]
		public void ProcessInputFolder()
		{
			var cfg = new ExcelAutomatorConfiguration()
			{
				Settings = new SettingsConfiguration()
				{
					Input = Path.Combine(Environment.CurrentDirectory, "Input")
				}
			};

			var sut = new ExcelAutomationService(cfg);

			Assert.That(sut.InputFiles.Count, Is.EqualTo(3));
		}
		#endregion

		#region ResolveExecutorSets
		[Test]
		public void ResolveExecutorSets()
		{
			var cfg =
				ExcelAutomatorConfiguration.FromXml(
					TestHelper.GetStringResource("ExcelAutomator.Tests.Resources.MultipleExecutorSets.xml"));

			var sut = new ExcelAutomationService(cfg);

			Assert.That(sut.ExecutorSets.Count, Is.EqualTo(2));
			Assert.That(sut.ExecutorSets.First().Id, Is.EqualTo("My Execution Batch 1"));
			Assert.That(sut.ExecutorSets.Last().Id, Is.EqualTo("My Execution Batch 2"));

		}
		#endregion

		#region ResolveExecutors
		[Test]
		public void ResolveExecutors()
		{
			var cfg =
				ExcelAutomatorConfiguration.FromXml(
					TestHelper.GetStringResource("ExcelAutomator.Tests.Resources.MultipleExecutorSets.xml"));

			var sut = new ExcelAutomationService(cfg);

			var executorsSet1 = sut.ExecutorSets.First().Executors;
			var executorsSet2 = sut.ExecutorSets.Last().Executors;

			Assert.That(executorsSet1.Count(), Is.EqualTo(3));
			Assert.That(executorsSet2.Count(), Is.EqualTo(2));

		}
		#endregion

		#region EnsureThatSingleInputFileWillResultToBeTheTargetIfNoTargetIsExplicitlySpecified
		[Test]
		public void EnsureThatSingleInputFileWillResultToBeTheTargetIfNoTargetIsExplicitlySpecified()
		{
			var cfg =
				ExcelAutomatorConfiguration.FromXml(
					TestHelper.GetStringResource("ExcelAutomator.Tests.Resources.SimpleExecutorSet.xml"));

			var sut = new ExcelAutomationService(cfg);

			Assert.That(sut.InputFiles.Count, Is.EqualTo(1));
			Assert.That(sut.TargetFiles.Count, Is.EqualTo(1));
			Assert.That(sut.InputFiles.First(), Is.EqualTo(Path.Combine(this.InputFolderPath, SourceWbName)));
			Assert.That(sut.TargetFiles.First(), Is.EqualTo(Path.Combine(this.InputFolderPath, SourceWbName)));

		}
		#endregion

		#region EnsureThatMultipleInputFilesResultToBeTheTargetsIfNoTargetIsExplicitlySpecified
		[Test]
		public void EnsureThatMultipleInputFilesResultToBeTheTargetsIfNoTargetIsExplicitlySpecified()
		{
			var cfg = new ExcelAutomatorConfiguration()
			           	{
			           		Settings = new SettingsConfiguration()
			           		           	{
			           		           		Input = "Input"
			           		           	}
			           	};

			var sut = new ExcelAutomationService(cfg);

			Assert.That(sut.InputFiles.Count, Is.EqualTo(3));
			Assert.That(sut.InputFiles.First(), Is.EqualTo(Path.Combine(this.InputFolderPath, SourceWbMacroName)));
			Assert.That(sut.InputFiles.Last(), Is.EqualTo(Path.Combine(this.InputFolderPath, SourceWbName2)));
			Assert.That(sut.TargetFiles.Count, Is.EqualTo(3));
			Assert.That(sut.TargetFiles.First(), Is.EqualTo(Path.Combine(this.InputFolderPath, SourceWbMacroName)));
			Assert.That(sut.TargetFiles.Last(), Is.EqualTo(Path.Combine(this.InputFolderPath, SourceWbName2)));
		}
		#endregion

		#region EnsureThatASpecifiedTargetFileWillResultTheInputFilesToBeMergedInTheTarget
		[Test]
		public void EnsureThatASpecifiedTargetFileWillResultTheInputFilesToBeMergedInTheTarget()
		{
			var cfg = new ExcelAutomatorConfiguration()
			           	{
			           		Settings = new SettingsConfiguration()
			           		           	{
			           		           		Input = @"Input\Book_source.xlsx",
			           		           		Target = @"Target\Book_target.xlsx"
			           		           	}
			           	};

			var sut = new ExcelAutomationService(cfg);

			Assert.That(sut.InputFiles.Count, Is.EqualTo(1));
			Assert.That(sut.TargetFiles.Count, Is.EqualTo(1));
			Assert.That(sut.TargetFiles.First(), Is.EqualTo(Path.Combine(Environment.CurrentDirectory + "\\Target", TargetWbName)));
		}
		#endregion

		#region ValidateConfigurationWithoutErrors
		[Test]
		public void ValidateConfigurationWithoutErrors()
		{
			var cfg =
				ExcelAutomatorConfiguration.FromXml(
					TestHelper.GetStringResource("ExcelAutomator.Tests.Resources.MultipleExecutorSets.xml"));
			var sut = new ExcelAutomationService(cfg);

			ValidationReport report;
			var isValid = sut.Validate(out report);

			Assert.That(isValid, Is.True);
			Assert.That(report.IsValid, Is.True);
			Assert.That(report.ViolationsCount, Is.EqualTo(0));

		}
		#endregion

		
		
		
		
		

		

		

		

		
		

		

		



		
		


		



		


		
		
		


	}
}
